#pragma once

#include "../../../Libs/headers.default.h"
#include "../../../Libs/headers.cv.h"
#include "../../../Libs/headers.classification.h"
#include "../../../Libs/headers.object_detection.h"
#include "../../../Libs/headers.ipfe.h"

using namespace loirey;

#define	USE_HOG	0

class CFileNameList
{
public:
	int FileAmount;

	vector<string> rgFN_Main;
	vector<string> rgFN_SrcImage;
	map<string, int> MainNameMap;

public:
	void myInit(string strFN_List, string strPN_SourceImage, string strFN_Sfx_SourceImage)
	{
		int i;
		ifstream inFile(strFN_List.c_str());
		MainNameMap.clear();
		inFile>>FileAmount;
		rgFN_Main.resize(FileAmount);
		rgFN_SrcImage.resize(FileAmount);
		for ( i = 0; i < FileAmount; ++i )
		{
			inFile>>rgFN_Main[i];
			MainNameMap[rgFN_Main[i]] = i;
			rgFN_SrcImage[i] = strPN_SourceImage + rgFN_Main[i] + strFN_Sfx_SourceImage;
		}
		inFile.clear();
		inFile.close();
	}
	void myInit(int FileAmount, string strPN_SrcImage, string strFN_Sfx_SrcImage)
	{
		int i;
		char fn[MAX_PATH];

		MainNameMap.clear();
		this->FileAmount = FileAmount;
		rgFN_Main.resize(FileAmount);
		rgFN_SrcImage.resize(FileAmount);
		for ( i = 0 ; i < FileAmount; ++i )
		{
			sprintf(fn,"%04d",i);
			rgFN_Main[i] = fn;
			MainNameMap[fn] = i;
			rgFN_SrcImage[i] = strPN_SrcImage + fn + strFN_Sfx_SrcImage;
		}
	}
	int GetFileIndex(string strFN_Main) const
	{
		map<string,int>::const_iterator citr = MainNameMap.find(strFN_Main);
		if (citr==MainNameMap.end())
			return -1;
		else
			return citr->second;
	}
};

class CPosNegFileNameSet
{
public:
	CFileNameList PosList, NegList;

public:
	void myInit(
		int PosFileAmount, string strPN_PosSrcImage,
		int NegFileAmount, string strPN_NegSrcImage,
		string strFN_Sfx_SrcImage
		)
	{
		PosList.myInit(PosFileAmount, strPN_PosSrcImage, strFN_Sfx_SrcImage);
		NegList.myInit(NegFileAmount, strPN_NegSrcImage, strFN_Sfx_SrcImage);
	}
};

class CGroundTruthReader_INRIA
{
public:
	static void ReadGroundTruthFile(CSimpleTypeArray<CRectBox<int>>& dstGtDetectionList, string strFN_ImageGroundTruth);
	static void ReadWhiteGtFile(CRectBox<int>& dstRectBox, string strFN_GroundTruthImage);
};

class CDataSet_INRIA_IPPFE : public CLabeledDataSetForClassification
{
public:
	class CExample
	{
	public:
		CImagePyramidPosition ipp;
		bool fIsPos;
		int ImageIndex;
	public:
		bool InputFromStream(ifstream& inStream, const CPosNegFileNameSet& PosNegFileNameSet);
		void OutputToStream(ofstream& outStream, const CPosNegFileNameSet& PosNegFileNameSet);

		static bool CompareByImageIndexThenPosNegThenBox (const CExample& a, const CExample& b);
	};

protected:
	CImagePyramidPositionFeatureExtractor* _pIPPFE;
	const CPosNegFileNameSet* _cpPosNegFileNameSet;
	string _strFN_LastImage;

public:
	int ExampleAmount;
	CExample* rgExample;

protected:
	void myRelease();
public:
	CDataSet_INRIA_IPPFE();
	~CDataSet_INRIA_IPPFE();
	void myInit(string strNodeListFileName, const CPosNegFileNameSet* cpPosNegFileNameSet, CImageFilterBank* pIFB);

	int GetFeatureDimension();
	int GetExampleAmount();
	int GetExampleLabel(int NodeIndex);
	double GetExampleInitialWeight(int NodeIndex);
	double GetExampleFeature(int NodeIndex, int FeatureIndex);
};

